﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace FakeUnity.Warp
{
    public static class FrameworkNative
    {
        public const string nativelib = "TTEngine.Native";

        //所有字符串接口统一使用utf16,如需转换 c++侧处理
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern int App_MainLoop(string title, Action onInit, Action onUpdate, Action onGUI, Action onExit);
        public unsafe delegate void deleOnLog(char* log);
        [DllImport(nativelib)]
        public unsafe static extern int APP_SetLogger(deleOnLog onLog);
        
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern int App_UpdateFontTex();


        public unsafe delegate void deleOnIMAssert(char* _expr, char* filename, int line);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void SetAssertCallBack(deleOnIMAssert callback);

        /// <summary>
        /// //////////////////////////////////////////////////////////////////
        /// //繪製接口
        /// </summary>
        public struct TargetHandle
        {
            public IntPtr ptr;
        }
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern TargetHandle Target_Create(int width, int height);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Target_Destory(TargetHandle handle);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Target_Reset(TargetHandle handle, int width, int height);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern IntPtr Target_GetImGuiTexID(TargetHandle handle);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void MainScreen_Reset(TargetHandle handle, int width, int height);


        /// <summary>
        /// ////////////////////////////
        /// </summary>
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Frame_SetTarget(TargetHandle handle);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Frame_SetMainScreen();
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Frame_Clear(UInt32 color, bool withColor, bool withDepth);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Frame_Flush();




        public struct XYWH
        {
            int x;
            int y;
            int w;
            int h;
        };
        public struct Vector4
        {
            float x;
            float y;
            float z;
            float w;
        };
        public struct Matrix
        {
            float m11;
            float m12;
            float m13;
            float m14;
            float m21;
            float m22;
            float m23;
            float m24;
            float m31;
            float m32;
            float m33;
            float m34;
            float m41;
            float m42;
            float m43;
            float m44;
        }
        public struct Texture
        {
            public IntPtr ptr;
        }

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern Texture Texture_LoadFromFile(string filename);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern Texture Texture_LoadFromMem(IntPtr mem, UInt32 size);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern Texture Texture_Create(UInt32 width, UInt32 height, IntPtr memInit);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Texture_Upload(Texture texture, XYWH xywh, IntPtr mem, int size, int pitch);


        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Texture_Destory(Texture handle);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern IntPtr Texture_GetImGuiTexID(Texture handle);

        public struct Material
        {
            public IntPtr ptr;
        }

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern Material Material_Create(string shadername);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Material_Destory(Material material);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern int Material_GetUniformCount(Material material);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern string Material_GetUniformName(Material material, int index);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern IntPtr Material_GetUniformNameHash(Material material, int index);
        public enum UniformType : byte //和bgfx保持一致
        {
            Sampler, //!< Sampler. 贴图
            End,     //!< Reserved, do not use.

            Vec4,    //!< 4 floats vector.
            Mat3,    //!< 3x3 matrix.
            Mat4,    //!< 4x4 matrix.

            Count
        };
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern UniformType Material_GetUniformType(Material material, int index);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Material_SetTexture(Material material, int uniformID, Texture texture);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Material_SetVec4(Material material, int uniformID, Vector4 value);

        public struct Mesh
        {
            public  IntPtr ptr;
        }

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern Mesh Mesh_CreateSample();



        public enum VertexFormat
        {
            Nothing,
            Pos,
            Pos_Color0,
            Pos_UV0_Color0,
            Pos_UV0_UV1_Color0_Color1,
            Pos_UV0_UV1_UV2_Color0_Color1_Color2,
            Pos_UV0_UV1_UV2_UV3_Color0_Color1_Color2_Color3,
        };
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern Mesh Mesh_Create(VertexFormat format, int vertexCount, int triCount, IntPtr memVB, IntPtr memIB);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Mesh_Destory(Mesh handle);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern int Mesh_GetVertexStride(Mesh handle);

        //动态模型可以随时更新
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern Mesh MeshDynamic_Create(VertexFormat format, int vertexCount, int triCount);
      
        
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]

        public static extern void MeshDynamic_UploadVertex(Mesh mesh, int VertexStart, int VertexCount, IntPtr mem);
        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern unsafe void MeshDynamic_UploadIndex(Mesh mesh, int IndexStart, int IndexCount, UInt16* indexdata);

        [DllImport(nativelib, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
        public static extern void Frame_Draw(Material mat, Mesh mesh);

    }
}
